/******************************************************************************************************************
 * File:DoorSensor.java
 * Course: 17655
 * Project: Assignment A3
 * Copyright: Copyright (c) 2009 Carnegie Mellon University
 * Versions:
 *	1.0 March 2009 - Initial rewrite of original assignment 3 (ajl).
 *
 * Description:
 *
 * This class simulates a Door sensor. It polls the event manager for events corresponding to changes in state
 * of the humidifier or dehumidifier and reacts to them by trending the relative Door up or down. The current
 * relative Door is posted to the event manager.
 *
 * Parameters: IP address of the event manager (on command line). If blank, it is assumed that the event manager is
 * on the local machine.
 *
 * Internal Methods:
 *	float GetRandomNumber()
 *	boolean CoinToss()
 *   void PostDoor(EventManagerInterface ei, float Door )
 *
 ******************************************************************************************************************/
import InstrumentationPackage.*;
import EventPackage.*;

import java.util.*;

class DoorSensor {
	static MessageWindow mw = null;
	static boolean controlFlag = false;

	public static void main(String args[]) {
		String EvtMgrIP; // Event Manager IP address
		Event Evt = null; // Event object
		EventQueue eq = null; // Message Queue
		int EvtId = 0; // User specified event ID
		EventManagerInterface em = null; // Interface object to the event
											// manager
		boolean WindowState = false; // Window state: false == not broken, true
										// == broken
		int Delay = 1000; // The loop delay (2.5 seconds)
		boolean Done = false; // Loop termination flag

		// ///////////////////////////////////////////////////////////////////////////////
		// Get the IP address of the event manager
		// ///////////////////////////////////////////////////////////////////////////////

		if (args.length == 0) {
			// event manager is on the local system

			System.out
					.println("\n\nAttempting to register on the local machine...");

			try {
				// Here we create an event manager interface object. This
				// assumes
				// that the event manager is on the local machine

				em = new EventManagerInterface();
			}

			catch (Exception e) {
				System.out
						.println("Error instantiating event manager interface: "
								+ e);

			} // catch

		} else if (args.length > 1) {
			// case where ip and binding name and passed along as command line
			// args
			long beatTime = 5000;

			// Send heart beat in default time interview

			try {
				// Here we create an event manager interface object. This
				// assumes
				// that the event manager is NOT on the local machine

				em = new EventManagerInterface(args[0], args[1]);
				if (args.length > 2) {
					// Launching heartbeat
					try {
						// Here we create an heart beat event manager interface
						// object. This
						// assumes
						// that the event manager is NOT on the local machine
						EventManagerInterface hbManager = new EventManagerInterface(
								args[2], args[3]);
						EventPackage.Event evt = new Event((int) 12);
						evt.SetSenderId(em.GetMyId());
						HeartBeat.startThread(hbManager, evt, beatTime);

						if (args.length == 6) {
							String name = args[4];
							String description = args[5];
							EventPackage.Event evt2 = new Event((int) 11, name
									+ '%' + description);
							evt2.SetSenderId(em.GetMyId());
							HeartBeat.startThread(hbManager, evt2, 30000);

						}
					} catch (Exception exp) {
						System.out.println("Failed starting Heartbeat");
					}
				}

			} catch (Exception e) {
				System.out
						.println("Error instantiating event manager interface: "
								+ e);

			} // catch
		} else {

			// event manager is not on the local system

			EvtMgrIP = args[0];

			System.out.println("\n\nAttempting to register on the machine:: "
					+ EvtMgrIP);

			try {
				// Here we create an event manager interface object. This
				// assumes
				// that the event manager is NOT on the local machine

				em = new EventManagerInterface(EvtMgrIP);
			}

			catch (Exception e) {
				System.out
						.println("Error instantiating event manager interface: "
								+ e);

			} // catch

		} // if

		if (em != null) {

			// We create a message window. Note that we place this panel about
			// 1/2 across
			// and 2/3s down the screen

			float WinPosX = 0.7f; // This is the X position of the message
									// window in terms
									// of a percentage of the screen height
			float WinPosY = 0.80f; // This is the Y position of the message
									// window in terms
									// of a percentage of the screen height

			mw = new MessageWindow("Window Sensor", WinPosX, WinPosY);

			mw.WriteMessage("Registered with the event manager.");

			try {
				mw.WriteMessage("   Participant id: " + em.GetMyId());
				mw.WriteMessage("   Registration Time: "
						+ em.GetRegistrationTime());

			} // try

			catch (Exception e) {
				mw.WriteMessage("Error:: " + e);

			} // catch

			mw.WriteMessage("Door Sensors Activated!");
		}

		while (!Done) {
			// Post the current relative Door

			// Get the message queue

			try {
				eq = em.GetEventQueue();

			} // try

			catch (Exception e) {
				System.out.println("Error getting event queue::" + e);

			} // catch

			// If there are messages in the queue, we read through them.
			// We are looking for EventIDs = -4, this means the the humidify or
			// dehumidifier has been turned on/off. Note that we get all the
			// messages
			// from the queue at once... there is a 2.5 second delay between
			// samples,..
			// so the assumption is that there should only be a message at most.
			// If there are more, it is the last message that will effect the
			// output of the Door as it would in reality.

			int qlen = eq.GetSize();

			for (int i = 0; i < qlen; i++) {
				Evt = eq.GetEvent();

				if (Evt.GetEventId() == -6) {

					if (Evt.GetMessage().equalsIgnoreCase("DB")) // humidifier
																	// off
					{
						WindowState = true;
						controlFlag = true;

					} // if
					if (Evt.GetMessage().equalsIgnoreCase("DS")) // humidifier
																	// off
					{
						WindowState = false;
						controlFlag = false;

					} // if

				} // if

				// If the event ID == 99 then this is a signal that the
				// simulation
				// is to end. At this point, the loop termination flag is set to
				// true and this process unregisters from the event manager.

				if (Evt.GetEventId() == 99) {
					Done = true;

					try {
						em.UnRegister();

					} // try

					catch (Exception e) {
						System.out.println("Error unregistering: " + e);

					} // catch

					System.out.println("\n\nSimulation Stopped. \n");

				} // if

			} // for

			// Now we trend the relative Door according to the status of the
			// humidifier/dehumidifier controller.

			if (controlFlag) {
				if (WindowState) {
					PostWindowEvent(em, true);
					// controlFlag = false;

				} // if humidifier is on

			}

			// Here we wait for a 2.5 seconds before we start the next sample

			try {
				Thread.sleep(Delay);

			} // try

			catch (Exception e) {
				System.out.println("Sleep error:: " + e);

			} // catch

		} // while

	} // main



	static private void PostWindowEvent(EventManagerInterface ei, boolean broken) {
		// Here we create the event.

		Event evt = null;

		if (broken) {
			evt = new Event((int) 6, "DB");
			mw.WriteMessage("Door Broken!");
		}

		// Here we send the event to the event manager.

		try {
			ei.SendEvent(evt);
			// mw.WriteMessage( "Sent Door Event" );

		} // try

		catch (Exception e) {
			System.out.println("Error Posting Window status:: " + e);

		} // catch

	} // PostDoor

} // Door Sensor
